home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / Wavy / Experiments / dynamicMap / dynamicmap.c next >
C/C++ Source or Header  |  1993-06-18  |  10KB  |  410 lines

  1. /*
  2.     Test mappings
  3. */
  4.  
  5. #include <QDOffscreen.h>
  6. #include <FixMath.h>
  7.  
  8. #include "instructions.h"
  9.  
  10. long Microseconds() = 0xA093;
  11.  
  12. #define pictID    128
  13. #define    kFrameCount 16        // 16 and 32 are kinda nice
  14.  
  15.  
  16. void
  17. MakeSineTable(short *theTable)
  18. {
  19.     
  20. #define    cycleSize (kFrameCount / 2)
  21. #define twoPiOverCycleSize (205887/cycleSize)
  22. #define    amplitude 4
  23.  
  24.     short    i;
  25.     
  26.     for (i = 0; i < 32; i++)
  27.         *theTable++ = (amplitude * Frac2Fix(FracSin(i * twoPiOverCycleSize))+32768) >> 16;
  28.  
  29. }
  30. void MapCoordinates(short width, short height, short x, short y,
  31.                     short *resultX, short *resultY,
  32.                     short frameNumber,
  33.                     short *theTable)
  34.  
  35. {
  36. #define HorizontalSineWave 0
  37. #define VerticalSineWave 1
  38. #define Mirror 0
  39. #define Identity 0
  40.  
  41.  
  42. #if Identity 
  43.     *resultX = x;
  44.     *resultY = y;
  45. #endif
  46.  
  47. #if Mirror
  48.     *resultX = width - x;
  49.     *resultY = y;
  50. #endif
  51.  
  52. #if HorizontalSineWave
  53.     *resultX = x + (18 * Frac2Fix(FracSin(y * twoPiOverCycleSize))+32768) >> 16;
  54.     *resultY = y;
  55. #endif
  56.  
  57. #if VerticalSineWave
  58.     *resultX = x;
  59.     *resultY = y + theTable[(x + frameNumber) % 32];
  60. #endif
  61.         
  62.     while (*resultX < 0)
  63.         *resultX += width;
  64.     while (*resultY < 0)
  65.         *resultY += height;
  66.  
  67.     *resultX %= width;
  68.     *resultY %= height;
  69. }
  70.  
  71. /*
  72.     Generate the addresses for one 32-pixel column. 
  73. */
  74.  
  75. void
  76. GenerateMappingColumn(    long    *buffer1, short width, short height, short rowBytes,
  77.                          short frameNumber, short *theTable)
  78. {
  79.     long    *offsetHere;
  80.     short    x, y;
  81.     
  82.     offsetHere = buffer1;
  83.  
  84.     for (y = 0; y < height; ++y) {
  85.         for (x = 0; x < 32; ++x)
  86.             {
  87.             short    destinationX, destinationY;
  88.  
  89.             MapCoordinates(width, height, x, y, &destinationX, &destinationY,
  90.                              frameNumber, theTable);
  91.             *offsetHere++ = (long)destinationY * rowBytes + destinationX;
  92.             }
  93.     }
  94. }
  95.  
  96. void
  97. BlitOneColumn(char    *sourceBase, char *destinationBase, short height,
  98.                 short rowBytes, long *columnMapping)
  99.                 
  100. {
  101.     short    x, y;
  102.     char    *sourceRow, *sourceByte;
  103.     long    *offsetHere;
  104.             
  105.     for (y = 0; y < height; ++y)
  106.         {
  107.         short    byte;
  108.  
  109.         sourceByte = sourceBase;
  110.         for (byte = 0; byte < 32; ++byte)
  111.             *(destinationBase + *columnMapping++) = *sourceByte++;
  112.         sourceBase += rowBytes;
  113.         }
  114. }
  115.  
  116.  
  117. //
  118. // Blit the entire bitmap from source to dest using a technique similar to what
  119. // we'd like to compile.
  120. //
  121. //    Use 5 destination registers so we can use 16-bit constant offsets in instructions
  122. //    of the form:
  123. //
  124. //    move.b    (sourceRow)+, tableValue(destReg[0..4])
  125. //    
  126. //    
  127. #define    EMIT_POSTINC     0
  128.  
  129. void
  130. WriteSomeCode(short height, short rowBytes, long *mappingTable, short *theCode)
  131. {
  132.     short    i, x, y;
  133.     
  134.     long    destRegisters[5];
  135.     long    targetByte;
  136.     
  137.     *(*(short **) &theCode)++ = 0xa9ff;
  138.  
  139.     for (i = 0; i < 5; i++)
  140.         destRegisters[i] = 32768 + i * 65536L;
  141.  
  142.     for (y = 0; y < height; ++y)
  143.         {
  144.         for (x = 0; x < 32; ++x) {
  145.             long    registerOffset;
  146.             
  147.             targetByte = *mappingTable++;
  148.         
  149. #if EMIT_POSTINC        
  150.             for (i = 0; i < 5; i++) {
  151.                 registerOffset = targetByte - destRegisters[i];
  152.                 if (registerOffset >= -32768 && registerOffset < 32768) {
  153.                     switch(i) {
  154.                         case 0:
  155.                             *(*(short **) &theCode)++ = move_b_a5plus_a0;
  156.                             *(*(short **) &theCode)++ = registerOffset;
  157.                             break;
  158.                         case 1:
  159.                             *(*(short **) &theCode)++ = move_b_a5plus_a1;
  160.                             *(*(short **) &theCode)++ = registerOffset;
  161.                             break;
  162.                         case 2:
  163.                             *(*(short **) &theCode)++ = move_b_a5plus_a2;
  164.                             *(*(short **) &theCode)++ = registerOffset;
  165.                             break;
  166.                         case 3:
  167.                             *(*(short **) &theCode)++ = move_b_a5plus_a3;
  168.                             *(*(short **) &theCode)++ = registerOffset;
  169.                             break;
  170.                         case 4:
  171.                             *(*(short **) &theCode)++ = move_b_a5plus_a4;
  172.                             *(*(short **) &theCode)++ = registerOffset;
  173.                             break;
  174.                         default:
  175.                             Debugger();
  176.                             break;
  177.                     }                
  178.                     break;
  179.                 }
  180.             }
  181. #else
  182.             for (i = 0; i < 0; i++) {
  183.                 registerOffset = targetByte - destRegisters[i];
  184.                 if (registerOffset >= -32768 && registerOffset < 32768) {
  185.                     switch(i) {
  186.                         case 0:
  187.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a0;
  188.                             *(*(short **) &theCode)++ = x;
  189.                             *(*(short **) &theCode)++ = registerOffset;
  190.                             break;
  191.                         case 1:
  192.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a1;
  193.                             *(*(short **) &theCode)++ = x;
  194.                             *(*(short **) &theCode)++ = registerOffset;
  195.                             break;
  196.                         case 2:
  197.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a2;
  198.                             *(*(short **) &theCode)++ = x;
  199.                             *(*(short **) &theCode)++ = registerOffset;
  200.                             break;
  201.                         case 3:
  202.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a3;
  203.                             *(*(short **) &theCode)++ = x;
  204.                             *(*(short **) &theCode)++ = registerOffset;
  205.                             break;
  206.                         case 4:
  207.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a4;
  208.                             *(*(short **) &theCode)++ = x;                            
  209.                             *(*(short **) &theCode)++ = registerOffset;
  210.                             break;
  211.                         default:
  212.                             Debugger();
  213.                             break;
  214.                     }                
  215.                     break;
  216.                 }
  217.             }
  218.         // So, we have no register coverage for the destination
  219.         // We'll have to emit some slower code.
  220.         registerOffset = targetByte - 32768;
  221.         *(*(short **) &theCode)++ = immediate_long_load_d0;
  222.         *(*(long **) &theCode)++ = registerOffset;
  223.         *(*(short **) &theCode)++ = move_byte_da5_a0_d0_L;
  224.         *(*(short **) &theCode)++ = x;
  225.         *(*(short **) &theCode)++ = no_constant_for_load;
  226.         
  227. #endif
  228.         }
  229.         // add rowbytes to the row register
  230.         *(*(short **) &theCode)++ = adda_w_const_a5;
  231. #if EMIT_POSTINC
  232.         *(*(short **) &theCode)++ = rowBytes - 32;
  233. #else
  234.         *(*(short **) &theCode)++ = rowBytes;
  235. #endif
  236.     
  237.     }
  238.     *(*(short **) &theCode)++ = rts;
  239. }
  240.  
  241. //
  242. // Blit the entire bitmap from source to dest, using the same column
  243. // mappings for each column across
  244. //
  245.  
  246. void
  247. BlitColumns(char *sourceBase, char *destinationBase, short height, short width,
  248.             short rowBytes, long *columnMapping)
  249. {
  250.     short    x, y;
  251.     char    *sourceRow, *sourceByte;
  252.     long    *offsetHere;
  253.     
  254.     for (x = 0; x < width; x += 32)
  255.         {
  256.         char    *destinationRow;
  257.  
  258.         offsetHere = columnMapping;
  259.         sourceRow = sourceBase + x;
  260.         destinationRow = destinationBase + x;
  261.  
  262.         BlitOneColumn(sourceRow, destinationRow, height, rowBytes, offsetHere);
  263.         }
  264. }
  265.  
  266. main()
  267. {
  268.     WindowPtr        sourceWindow, destinationWindow;
  269.     Rect            sourceRect, destRect;
  270.     Rect            frame;
  271.     PicHandle        picture;
  272.     GWorldPtr        sourceGWorld, destinationGWorld;
  273.     PixMapHandle    sourcePix, destinationPix;
  274.     GWorldPtr        savedGWorld;
  275.     GDHandle        savedGDevice;
  276.     short            height, width, rowBytes;
  277.     short            i, x, y;
  278.     long            *buffer1, *offsetHere;
  279.     char            *sourceBase, *destinationBase;
  280.     long            *ColumnMaps[kFrameCount];
  281.     short            *FrameCode[kFrameCount];
  282.     short            wavyTable[32];
  283.  
  284.     InitGraf(&qd.thePort);
  285.     InitWindows();
  286.     
  287.     picture = GetPicture(pictID);
  288.  
  289.     frame = (**picture).picFrame;
  290.     width = frame.right - frame.left;
  291.     height = frame.bottom - frame.top;
  292.     SetRect(&sourceRect, 50, 50, width + 50, height + 50);
  293.     destRect = sourceRect;
  294.     OffsetRect(&destRect, 0, 220);
  295.  
  296.     sourceWindow = NewCWindow(nil,&sourceRect,
  297.                             "\pSource", TRUE,
  298.                             documentProc, (WindowPtr)(-1), FALSE, 0);
  299.                             
  300.     destinationWindow = NewCWindow(nil,&destRect,
  301.                             "\pDestination", TRUE,
  302.                             documentProc, (WindowPtr)(-1), FALSE, 0);
  303.     
  304.     GetGWorld(&savedGWorld, &savedGDevice);
  305.     NewGWorld(&sourceGWorld,8,&frame,nil,nil,0);
  306.     NewGWorld(&destinationGWorld,8,&frame,nil,nil,0);
  307.     sourcePix = GetGWorldPixMap(sourceGWorld);
  308.     LockPixels(sourcePix);
  309.     SetGWorld(sourceGWorld, nil);
  310.     DrawPicture(picture,&sourceGWorld->portRect);
  311.     UnlockPixels(sourcePix);
  312.     LockPixels(destinationPix);
  313.     SetGWorld(destinationGWorld, nil);
  314.     EraseRect(&destinationGWorld->portRect);
  315.     UnlockPixels(destinationPix);
  316.     SetGWorld(savedGWorld, savedGDevice);
  317.  
  318.     sourcePix = GetGWorldPixMap(sourceGWorld);
  319.     destinationPix = GetGWorldPixMap(destinationGWorld);
  320.     rowBytes = (**GetGWorldPixMap(sourceGWorld)).rowBytes & 0x7FFF;
  321.  
  322.     SetPort(sourceWindow);
  323.     LockPixels(sourcePix);
  324.     CopyBits((BitMap *)*sourcePix, &sourceWindow->portBits,
  325.          &sourceGWorld->portRect, &sourceWindow->portRect, srcCopy, nil);
  326.     UnlockPixels(sourcePix);
  327.  
  328.     SetPort(destinationWindow);
  329.     LockPixels(sourcePix);
  330.     LockPixels(destinationPix);
  331.     
  332.     MakeSineTable(wavyTable);
  333.     
  334.     for (x = 0; x < kFrameCount; x++)
  335.     {
  336.         ColumnMaps[x] = (long *)NewPtr(sizeof(long) * 32 * height);
  337.         if (ColumnMaps[x] == nil)
  338.             Debugger();
  339.  
  340.         FrameCode[x] = (short *) NewPtr(12L * 32 * height        // move the rows
  341.                                         + 6 * 20 * height        // the row reloads
  342.                                         + 500);                    // el sloppolo
  343.         if (FrameCode[x] == nil)
  344.             Debugger();
  345.  
  346.         GenerateMappingColumn(ColumnMaps[x], width, height, rowBytes, x, wavyTable);
  347.         WriteSomeCode(height, rowBytes, ColumnMaps[x], FrameCode[x]);
  348.         
  349. //        DisposePtr((Ptr)ColumnMaps[x]);
  350.  
  351.         MoveTo(width / 2 - 20, x * 3 + 10);            // amuse the user
  352.         LineTo(width / 2 + 20, x * 3 + 10);
  353.     }
  354.  
  355.     SetPort(destinationWindow);
  356.  
  357.     sourceBase = (**sourcePix).baseAddr;
  358.     destinationBase = (**destinationPix).baseAddr;
  359.         
  360.     while (!Button()) {
  361.         short    *theCode;
  362.         char    *sourceRow;
  363.         char    *destinationRow;
  364.  
  365.         long    startTime, endTime;
  366.         for (i = 0; i < kFrameCount ; i++) {
  367.             theCode = FrameCode[i];
  368.  
  369. //            BlitColumns(sourceBase, destinationBase, height, width,
  370. //                    rowBytes, ColumnMaps[i]);
  371.  
  372.             for (x = 0; x < width; x += 32) {
  373.                 sourceRow = sourceBase + x;
  374.                 destinationRow = destinationBase + x;
  375.                 
  376.                 startTime = Microseconds();
  377.                 asm {
  378.                     movem.l    a0-a6, -(sp)
  379.                     
  380.                     movea.l    destinationRow, a0
  381.                     adda.l    #0x8000, a0
  382.                     movea.l    a0, a1
  383.                     adda.l    #0x10000, a1
  384.                     movea.l    a1, a2
  385.                     adda.l    #0x10000, a2
  386.                     movea.l    a2, a3
  387.                     adda.l    #0x10000, a3
  388.                     movea.l    a3, a4
  389.                     adda.l    #0x10000, a4
  390.                     movea.l    sourceRow, a5
  391.         
  392.                     movea.l    theCode, a6
  393.                     jsr        (a6)                // whee!
  394.                     movem.l    (sp)+, a0-a6
  395.                 }
  396.                 endTime = Microseconds();
  397.                 Debugger();
  398.             }
  399.  
  400.             CopyBits((BitMap *)*destinationPix, &destinationWindow->portBits,
  401.                  &destinationGWorld->portRect, &destinationWindow->portRect, srcCopy, nil);
  402.             if (Button())
  403.                 break;
  404.         }
  405.     }
  406.     
  407.     UnlockPixels(sourcePix);
  408.     UnlockPixels(destinationPix);
  409. }
  410.